package rexsee.core.transportation;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;

import rexsee.core.application.RexseeApplication;
import rexsee.core.browser.Browser;
import rexsee.core.browser.clazz.FileSelector;
import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.lang.RexseeLanguage;
import android.net.Uri;
import android.os.Environment;
import android.webkit.CookieManager;

public class RexseeUpload implements JavascriptInterface {

	public static final String INTERFACE_NAME = "Upload";
	@Override
	public String getInterfaceName() {
		return mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return new RexseeUpload(childBrowser);
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseeUpload(childBrowser);
	}

	public static final String EVENT_ONUPLOADFILESELECTED = "onUploadFileSelected";
	public static final String EVENT_ONUPLOADFILESELECTIONFAILED = "onUploadFileSelectionFailed";
	public static final String EVENT_ONUPLOADPROGRESSCHANGED = "onUploadProgressChanged";
	public static final String EVENT_ONUPLOADFINISHED = "onUploadFinished";
	public static final String EVENT_ONUPLOADTIMEOUT = "onUploadTimeout";
	public static final String EVENT_ONUPLOADSFINISHED = "onUploadsFinished";

	public static final int UPLOAD_PROGRESS_FINISHED = 2; //Returned from server
	public static final int UPLOAD_PROGRESS_DONE = 1; //Upload finished, waiting for server
	public static final int UPLOAD_PROGRESS_ONGOING = 0;
	public static final int UPLOAD_PROGRESS_CONNECTING = -1;
	public static final int UPLOAD_PROGRESS_TIMEOUT = -2;
	public static final int UPLOAD_PROGRESS_EXCEPTION = -3;

	public static final String LINEEND = "\r\n";
	public static final String DOUBLEHYPHENS = "--";
	public static final String BOUNDARY = "*****";
	private static String syncUploadProgress = null;

	public static abstract class UploadProgressListener {
		public abstract void run(String action, final String name, String path, int status, int totalSize, int uploadedSize, String message, Runnable stopTheUpload);
	}

	public final ArrayList<String> selectedFiles = new ArrayList<String>();

	protected final Browser mBrowser;
	private int uploadIndex = -1;

	public RexseeUpload(Browser browser) {
		super();
		mBrowser = browser;
		mBrowser.eventList.add(EVENT_ONUPLOADFILESELECTED);
		mBrowser.eventList.add(EVENT_ONUPLOADFILESELECTIONFAILED);
		mBrowser.eventList.add(EVENT_ONUPLOADPROGRESSCHANGED);
		mBrowser.eventList.add(EVENT_ONUPLOADFINISHED);
		mBrowser.eventList.add(EVENT_ONUPLOADTIMEOUT);
		mBrowser.eventList.add(EVENT_ONUPLOADSFINISHED);
	}

	public static void upload(final Browser browser, final String action, final String name, final String path, final UploadProgressListener progressListener) {
		if (progressListener == null) {
			browser.exception(RexseeDownload.class.getName(), "Progress listener could not be null.");
			return;
		}
		final String uploadUrl = browser.urlListeners.getAbsoluteUrl(action);
		String scheme = Uri.parse(uploadUrl).getScheme();
		if (!scheme.equals("http") && !scheme.equals("https")) {
			progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, "Wrong Scheme!", null);
			browser.exception(RexseeUpload.class.getName(), action + ":Wrong Scheme!");
			return;
		}
		if (!browser.domainWhiteList.isValidUrl(uploadUrl)) {
			progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, "Url not allowed.", null);
			browser.exception(RexseeUpload.class.getName(), action + ":Url not allowed.");
			return;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
			progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, "SD card is not ready.", null);
			browser.exception(RexseeUpload.class.getName(), "SD card is not ready.");
			return;
		}
		final String fileName = path.substring(path.lastIndexOf("/") + 1);
		Uri uri = Uri.parse(path);
		if (!uri.getScheme().equals("file")) {
			progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, "Invalid scheme.", null);
			browser.exception(RexseeUpload.class.getName(), path + ":Invalid scheme.");
			return;
		}
		final File file = new File(uri.getPath());
		if (!file.exists() || !file.isFile()) {
			progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, "File not found.", null);
			browser.exception(RexseeUpload.class.getName(), path + ":File not found.");
			return;
		}
		if (!file.canRead()) {
			progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, "File not readable.", null);
			browser.exception(RexseeUpload.class.getName(), path + ":File not readable.");
			return;
		}
		new Thread() {
			private boolean stop = false;
			private final Runnable stopRunnable = new Runnable() {
				@Override
				public void run() {
					stop = true;
					progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, "User canceled.", null);
				}
			};
			@Override
			public void run() {
				int timeout = browser.application.getTimeout() * 1000;
				try {
					progressListener.run(action, name, path, UPLOAD_PROGRESS_CONNECTING, 0, 0, null, stopRunnable);
					URL url = new URL(uploadUrl);
					HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
					urlConnection.setRequestMethod("POST");
					urlConnection.setDoInput(true);
					urlConnection.setDoOutput(true);
					urlConnection.setChunkedStreamingMode(2 * 1024 * 1024);
					urlConnection.setConnectTimeout(timeout);
					urlConnection.setReadTimeout(timeout);
					urlConnection.setUseCaches(false);
					CookieManager cookieManager = CookieManager.getInstance();
					String cookie = cookieManager.getCookie(uploadUrl);
					if (cookie != null) {
						urlConnection.setRequestProperty("Cookie", cookie);
						//After urlConnection.connect(); could retrieve sessionId with urlConnection.getHeaderField("Set-Cookie");
					}
					urlConnection.setRequestProperty("User-Agent", browser.getSettings().getUserAgentString());
					urlConnection.setRequestProperty("Connection", "Keep-Alive");
					urlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
					urlConnection.connect();
					BufferedOutputStream dos = new BufferedOutputStream(urlConnection.getOutputStream(), 8192);
					dos.write((DOUBLEHYPHENS + BOUNDARY + LINEEND).getBytes());
					dos.write(("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + fileName + "\"; " + LINEEND).getBytes());
					//dos.writeBytes("Content-Disposition: form-data; name=" + name + "; filename=" + fileName + "; " + LINEEND);
					dos.write(LINEEND.getBytes());
					FileInputStream fileInputStream = new FileInputStream(file);
					int totalSize = fileInputStream.available();
					int uploadedSize = 0;
					byte[] buffer = new byte[1024];
					int bufferLength = 0;
					while ((bufferLength = fileInputStream.read(buffer)) > 0 && !stop) {
						dos.write(buffer, 0, bufferLength);
						uploadedSize += bufferLength;
						progressListener.run(action, name, path, UPLOAD_PROGRESS_ONGOING, totalSize, uploadedSize, null, stopRunnable);
					}
					dos.write(LINEEND.getBytes());
					dos.write((DOUBLEHYPHENS + BOUNDARY + DOUBLEHYPHENS + LINEEND).getBytes());
					fileInputStream.close();
					dos.flush();
					dos.close();
					progressListener.run(action, name, path, UPLOAD_PROGRESS_DONE, totalSize, uploadedSize, null, null);
					if (cookieManager.acceptCookie()) {
						////Set session cookie
						String cookieVal = null;
						String cookieKey = null;
						String sessionCookie = "";
						for (int i = 1; (cookieKey = urlConnection.getHeaderFieldKey(i)) != null; i++) {
							if (cookieKey.equalsIgnoreCase("set-cookie")) {
								cookieVal = urlConnection.getHeaderField(i);
								cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));
								sessionCookie += cookieVal + ";";
							} else {
							}
						}
						if (sessionCookie != "") cookieManager.setCookie(uploadUrl, cookieVal);
					}
					InputStream responseStream = urlConnection.getInputStream();
					InputStreamReader responseStreamReader = new InputStreamReader(responseStream);
					BufferedReader bufReader = new BufferedReader(responseStreamReader);
					String line = null;
					String response = "";
					while ((line = bufReader.readLine()) != null) {
						response += line;
					}
					responseStream.close();
					urlConnection.disconnect();
					browser.eventList.run(EVENT_ONUPLOADFINISHED, new String[]{path, response});
					progressListener.run(action, name, path, UPLOAD_PROGRESS_FINISHED, totalSize, uploadedSize, null, null);
				} catch (SocketTimeoutException ste) {
					if (!stop) {
						progressListener.run(action, name, path, UPLOAD_PROGRESS_TIMEOUT, 0, 0, String.valueOf(timeout), null);
						browser.eventList.run(EVENT_ONUPLOADTIMEOUT, new String[]{path, String.valueOf(timeout)});
					}
				} catch (Exception e) {
					if (!stop) {
						progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, e.getLocalizedMessage(), null);
						browser.exception(RexseeUpload.class.getName(), path + ":" + e.getLocalizedMessage());
					}
				}
			}
		}.start();
	}
	public static String syncUpload(final Browser browser, final String action, final String name, final String path, final boolean cancelable, final boolean hideProgress, final boolean filenameProgress) {
		syncUploadProgress = null;
		upload(browser, action, name, path, new UploadProgressListener() {
			@Override
			public void run(String action, String name, String path, int status, int totalSize, int uploadedSize, String message, final Runnable stopTheUpload) {
				String pName;
				if (filenameProgress) {
					String fileName = path.substring(path.lastIndexOf("/") + 1);
					pName = RexseeLanguage.PROGRESS_UPLOAD + fileName + "......";
				} else {
					pName = RexseeLanguage.PROGRESS_UPLOAD + "......";
				}
				if (status == UPLOAD_PROGRESS_CONNECTING) {
					if (cancelable) {
						browser.progressDialog.showWithRunnable(pName + "0%", stopTheUpload);
					} else {
						browser.progressDialog.show(pName + "0%");
					}
				} else if (status == UPLOAD_PROGRESS_TIMEOUT) {
					syncUploadProgress = RexseeApplication.EXCEPTION_PREFIX + message;
				} else if (status == UPLOAD_PROGRESS_EXCEPTION) {
					syncUploadProgress = RexseeApplication.EXCEPTION_PREFIX + message;
				} else if (status == UPLOAD_PROGRESS_FINISHED) {
					syncUploadProgress = "";
				} else if (status == UPLOAD_PROGRESS_ONGOING) {
					String progress = (totalSize < 0) ? "" : (uploadedSize * 100 / totalSize) + "%";
					if (cancelable) {
						browser.progressDialog.showWithRunnable(pName + progress + " ", stopTheUpload);
					} else {
						browser.progressDialog.show(pName + progress + " ");
					}
				} else if (status == UPLOAD_PROGRESS_DONE) {
					if (cancelable) {
						browser.progressDialog.showWithRunnable(RexseeLanguage.PROGRESS_WAITING_FOR_SERVER, stopTheUpload);
					} else {
						browser.progressDialog.show(RexseeLanguage.PROGRESS_WAITING_FOR_SERVER);
					}
				}
			}
		});
		while (syncUploadProgress == null) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
			}
		}
		if (hideProgress) browser.progressDialog.hide();
		return syncUploadProgress;
	}
	public static String syncUpload(final Browser browser, final String action, final String name, ArrayList<String> selectedFiles, final boolean cancelable) {
		if (selectedFiles == null || selectedFiles.size() == 0) return RexseeApplication.EXCEPTION_PREFIX + "No file selected.";
		for (int i = 0; i < selectedFiles.size(); i++) {
			String rtn = syncUpload(browser, action, name, selectedFiles.get(i), cancelable, false, true);
			if (!rtn.equals("")) {
				browser.progressDialog.hide();
				return rtn;
			}
		}
		browser.progressDialog.hide();
		return "";
	}

	/*
	public void upload(final String action, final String name, final UploadProgressListener progressListener) {
		final String uploadUrl = mBrowser.urlListeners.getAbsoluteUrl(action);
		String scheme = Uri.parse(uploadUrl).getScheme();
		if (!scheme.equals("http") && !scheme.equals("https")) {
			mBrowser.exception(getInterfaceName(), action + ":Wrong Scheme!");
			return;
		}
		if (!mBrowser.domainWhiteList.isValidUrl(uploadUrl)) {
			mBrowser.exception(getInterfaceName(), action + ":Url not allowed.");
			return;
		}
		if (progressListener == null) {
			mBrowser.exception(getInterfaceName(), action + ":Progress listener could not be null.");
			return;
		}
		if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
			mBrowser.exception(getInterfaceName(), "SD card is not ready.");
			return;
		}
		uploadIndex++;
		if (uploadIndex >= selectedFiles.size()) {
			uploadIndex = -1;
			mBrowser.eventList.run(EVENT_ONUPLOADSFINISHED);
		} else {
			final String path = selectedFiles.get(uploadIndex);
			final String fileName = path.substring(path.lastIndexOf("/") + 1);
			Uri uri = Uri.parse(path);
			if (!uri.getScheme().equals("file")) {
				mBrowser.exception(getInterfaceName(), path + ":Invalid scheme.");
				return;
			}
			final File file = new File(uri.getPath());
			if (!file.exists() || !file.isFile()) {
				mBrowser.exception(getInterfaceName(), path + ":File not found.");
				return;
			}
			if (!file.canRead()) {
				mBrowser.exception(getInterfaceName(), path + ":File not readable.");
				return;
			}
			new Thread() {
				private boolean stop = false;
				private final Runnable stopRunnable = new Runnable() {
					@Override
					public void run() {
						Toast.makeText(mContext, RexseeLanguage.PROGRESS_STOP, Toast.LENGTH_SHORT).show();
						stop = true;
					}
				};
				@Override
				public void run() {
					int timeout = mBrowser.application.getTimeout() * 1000;
					try {
						progressListener.run(action, name, path, UPLOAD_PROGRESS_CONNECTING, 0, 0, null, stopRunnable);
						URL url = new URL(Utilities.encodeUriComponent(uploadUrl));
						HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
						urlConnection.setRequestMethod("POST");
						urlConnection.setDoInput(true);
						urlConnection.setDoOutput(true);
						urlConnection.setConnectTimeout(timeout);
						urlConnection.setReadTimeout(timeout);
						urlConnection.setUseCaches(false);
						CookieManager cookieManager = CookieManager.getInstance();
						String cookie = cookieManager.getCookie(uploadUrl);
						if (cookie != null) {
							urlConnection.setRequestProperty("Cookie", cookie);
							//After urlConnection.connect(); could retrieve sessionId with urlConnection.getHeaderField("Set-Cookie");
						}
						urlConnection.setRequestProperty("User-Agent", mBrowser.getSettings().getUserAgentString());
						urlConnection.setRequestProperty("Connection", "Keep-Alive");
						urlConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
						urlConnection.connect();
						DataOutputStream dos = new DataOutputStream(urlConnection.getOutputStream());
						dos.writeBytes(DOUBLEHYPHENS + BOUNDARY + LINEEND);
						dos.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + fileName + "\"; " + LINEEND);
						//dos.writeBytes("Content-Disposition: form-data; name=" + name + "; filename=" + fileName + "; " + LINEEND);
						dos.writeBytes(LINEEND);
						FileInputStream fileInputStream = new FileInputStream(file);
						int totalSize = fileInputStream.available();
						int uploadedSize = 0;
						byte[] buffer = new byte[1024];
						int bufferLength = 0;
						while ((bufferLength = fileInputStream.read(buffer)) > 0 && !stop) {
							dos.write(buffer, 0, bufferLength);
							uploadedSize += bufferLength;
							progressListener.run(action, name, path, UPLOAD_PROGRESS_ONGOING, totalSize, uploadedSize, null, stopRunnable);
						}
						dos.writeBytes(LINEEND);
						dos.writeBytes(DOUBLEHYPHENS + BOUNDARY + DOUBLEHYPHENS + LINEEND);
						fileInputStream.close();
						dos.flush();
						dos.close();
						progressListener.run(action, name, path, UPLOAD_PROGRESS_DONE, totalSize, uploadedSize, null, null);
						if (cookieManager.acceptCookie()) {
							////Set session cookie
							String cookieVal = null;
							String cookieKey = null;
							String sessionCookie = "";
							for (int i = 1; (cookieKey = urlConnection.getHeaderFieldKey(i)) != null; i++) {
								if (cookieKey.equalsIgnoreCase("set-cookie")) {
									cookieVal = urlConnection.getHeaderField(i);
									cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));
									sessionCookie += cookieVal + ";";
								} else {
								}
							}
							if (sessionCookie != "") cookieManager.setCookie(uploadUrl, cookieVal);
						}
						InputStream responseStream = urlConnection.getInputStream();
						InputStreamReader responseStreamReader = new InputStreamReader(responseStream);
						BufferedReader bufReader = new BufferedReader(responseStreamReader);
						String line = null;
						String response = "";
						while ((line = bufReader.readLine()) != null) {
							response += line;
						}
						responseStream.close();
						urlConnection.disconnect();
						progressListener.run(action, name, path, UPLOAD_PROGRESS_FINISHED, totalSize, uploadedSize, null, null);
						mBrowser.eventList.run(EVENT_ONUPLOADFINISHED, new String[]{path, response});
						upload(uploadUrl, name, progressListener);
					} catch (SocketTimeoutException ste) {
						uploadIndex = -1;
						if (!stop) {
							progressListener.run(action, name, path, UPLOAD_PROGRESS_TIMEOUT, 0, 0, String.valueOf(timeout), null);
							mBrowser.eventList.run(EVENT_ONUPLOADTIMEOUT, new String[]{path, String.valueOf(timeout)});
						}
					} catch (Exception e) {
						uploadIndex = -1;
						if (!stop) {
							progressListener.run(action, name, path, UPLOAD_PROGRESS_EXCEPTION, 0, 0, e.getLocalizedMessage(), null);
							mBrowser.exception(getInterfaceName(), path + ":" + e.getLocalizedMessage());
						}
					}
				}
			}.start();
		}
	}
	*/

	//JavaScript Interface

	public int size() {
		return selectedFiles.size();
	}
	public boolean contains(String path) {
		return selectedFiles.contains(path);
	}
	public void select(String type) {
		clear();
		append(type);
	}
	public void append(String type) {
		mBrowser.fileSelector.selectByDefault(type, new FileSelector.FileSelecteListener() {
			@Override
			public void run(String path, String errorMessage) {
				if (path != null) {
					selectedFiles.add(path);
					mBrowser.eventList.run(EVENT_ONUPLOADFILESELECTED, new String[]{path});
				} else {
					mBrowser.eventList.run(EVENT_ONUPLOADFILESELECTIONFAILED, new String[]{errorMessage});
				}
			}
		});
	}
	public String get() {
		String rtn = "";
		for (int i = 0; i < selectedFiles.size(); i++) {
			rtn += (i == 0) ? "\"" + selectedFiles.get(i) + "\"" : ",\"" + selectedFiles.get(i) + "\"";
		}
		return "[" + rtn + "]";
	}
	public String get(int index) {
		if (index < 0 || index >= selectedFiles.size()) return "";
		else return selectedFiles.get(index);
	}
	public void clear() {
		selectedFiles.clear();
		uploadIndex = -1;
	}
	public int getCurrentIndex() {
		return uploadIndex;
	}

	public void upload(final String action, final String name) {
		upload(action, name, true);
	}
	public void upload(final String action, final String name, final boolean cancelable) {
		uploadIndex++;
		if (uploadIndex >= selectedFiles.size()) {
			uploadIndex = -1;
			mBrowser.progressDialog.hide();
			mBrowser.eventList.run(EVENT_ONUPLOADSFINISHED);
		} else {
			final String path = selectedFiles.get(uploadIndex);
			upload(mBrowser, action, name, path, new UploadProgressListener() {
				@Override
				public void run(String action, final String name, String path, int status, int totalSize, int uploadedSize, String message, final Runnable stopTheUpload) {
					if (status == UPLOAD_PROGRESS_CONNECTING) {
						if (cancelable) {
							mBrowser.progressDialog.showWithRunnable(RexseeLanguage.PROGRESS_CONNECT, stopTheUpload);
						} else {
							mBrowser.progressDialog.show(RexseeLanguage.PROGRESS_CONNECT);
						}
					} else if (status == UPLOAD_PROGRESS_TIMEOUT) {
						uploadIndex = -1;
						mBrowser.progressDialog.hide();
					} else if (status == UPLOAD_PROGRESS_EXCEPTION) {
						uploadIndex = -1;
						mBrowser.progressDialog.hide();
					} else if (status == UPLOAD_PROGRESS_FINISHED) {
						upload(action, name, cancelable);
					} else if (status == UPLOAD_PROGRESS_ONGOING) {
						String progress = (totalSize < 0) ? "" : (uploadedSize * 100 / totalSize) + "%";
						String fileName = path.substring(path.lastIndexOf("/") + 1);
						if (cancelable) {
							mBrowser.progressDialog.showWithRunnable(RexseeLanguage.PROGRESS_UPLOAD + fileName + "......" + progress + " ", stopTheUpload);
						} else {
							mBrowser.progressDialog.show(RexseeLanguage.PROGRESS_UPLOAD + fileName + "......" + progress + " ");
						}
					} else if (status == UPLOAD_PROGRESS_DONE) {
						if (cancelable) {
							mBrowser.progressDialog.showWithRunnable(RexseeLanguage.PROGRESS_WAITING_FOR_SERVER, stopTheUpload);
						} else {
							mBrowser.progressDialog.show(RexseeLanguage.PROGRESS_WAITING_FOR_SERVER);
						}
					}
				}
			});
		}
	}
	public void uploadWithCallback(final String action, final String name) {
		uploadIndex++;
		if (uploadIndex >= selectedFiles.size()) {
			uploadIndex = -1;
			mBrowser.progressDialog.hide();
			mBrowser.eventList.run(EVENT_ONUPLOADSFINISHED);
		} else {
			final String path = selectedFiles.get(uploadIndex);
			upload(mBrowser, action, name, path, new UploadProgressListener() {
				@Override
				public void run(String action, final String name, String path, int status, int totalSize, int uploadedSize, String message, final Runnable stopTheUpload) {
					mBrowser.eventList.run(EVENT_ONUPLOADPROGRESSCHANGED, new String[]{path, String.valueOf(totalSize), String.valueOf(uploadedSize), String.valueOf(status), String.valueOf(message)});
					if (status == UPLOAD_PROGRESS_CONNECTING) {
					} else if (status == UPLOAD_PROGRESS_TIMEOUT) {
						uploadIndex = -1;
					} else if (status == UPLOAD_PROGRESS_EXCEPTION) {
						uploadIndex = -1;
					} else if (status == UPLOAD_PROGRESS_FINISHED) {
						uploadWithCallback(action, name);
					} else if (status == UPLOAD_PROGRESS_ONGOING) {
					} else if (status == UPLOAD_PROGRESS_DONE) {
					}
				}
			});
		}
	}
	public String syncUpload(String action, String name) {
		return syncUpload(mBrowser, action, name, selectedFiles, true);
	}

}
